﻿using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
using Red.Core;
using Red.Core.Extensions;

namespace Red.Controls.Tile
{
    public class Tile : ViewModel
    {
        #region Public Types

        public interface IStrings
        {
            string Key { get; set; }
            string Header { get; set; }
            string ShortHeader { get; set; }
            string TinyHeader { get; set; }
            string Description { get; set; }
        }

        public class Strings : IStrings
        {
            public string Key { get; set; }
            public string Header { get; set; }
            public string ShortHeader { get; set; }
            public string TinyHeader { get; set; }
            public string Description { get; set; }
        }

        #endregion Public Types

        #region Private Data

        private int _colSpan = 1;
        private bool _isEnabled = true;

        #endregion Private Data

        #region Public Properties

        #region Serialised

        public int Id { get; set; }
        public int Row { get; set; }
        public int Column { get; set; }
        public int RowSpan { get; set; } = 1;
        public int ColumnSpan { get { return _colSpan; } set { _colSpan = value; OnPropertyChanged(); OnPropertyChanged( "Title" ); } }
        public string Function { get; set; }
        public string FunctionGroup { get; set; }
        public string Icon { get; set; }
        public string StatusBindingResource { get; set; }
        public bool Important { get; set; }

        #endregion Serialised

        #region Not Serialised

        public Canvas Canvas => ( Icon == null ) ? null : (Canvas)Application.Current.TryFindResource( Icon );
        public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; OnPropertyChanged(); } }
        public IStringProvider<IStrings> StringProvider { get; set; }
        public string Title => GetTitle();
        public string Description => GetDescription();
        public string Delete => Important ? "Hide" : "Delete";

        #endregion Not Serialised

        #endregion Public Properties

        #region Private Methods

        private string GetTitle( int columnSpan )
        {
            IStrings strings = StringProvider.GetValue( $"{FunctionGroup}.{Function}" );
            if ( strings != null )
            {
                if ( columnSpan == 2 && strings.ShortHeader != null )
                {
                    return strings.ShortHeader;
                }
                else if( columnSpan == 1 && strings.TinyHeader != null )
                {
                    return strings.TinyHeader;
                }

                return strings.Header;
            }

            return "Undefined";
        }

        private string GetTitle()
        {
            if ( StringProvider != null )
            {
                return GetTitle( ColumnSpan );
            }

            return Function;
        }

        private string GetDescription()
        {
            if ( StringProvider != null )
            {
                IStrings strings = StringProvider.GetValue( $"{FunctionGroup}.{Function}" );
                if ( strings != null )
                {
                    return strings.Description;
                }

                return "Undefined";
            }

            return Function;
        }

        #endregion Private Methods

        #region Public Methods

        public XElement ToXml()
        {
            XElement element = new XElement( "tile" );
            element.AddAttribute( "id", Id );
            element.AddAttribute( "row", Row );
            element.AddAttribute( "column", Column );
            element.AddAttribute( "rowspan", RowSpan );
            element.AddAttribute( "columnspan", ColumnSpan );
            element.AddAttribute( "functiongroup", FunctionGroup );
            element.AddAttribute( "function", Function );
            element.AddAttribute( "icon", Icon );
            element.AddAttribute( "statusresource", StatusBindingResource );
            element.AddAttribute( "important", Important );

            return element;
        }

        public static Tile FromXml( XElement element )
        {
            if ( element.Name == "tile" )
            {
                return new Tile()
                {
                    Id = element.GetAttribute<int>( "id" ),
                    Row = element.GetAttribute<int>( "row" ),
                    Column = element.GetAttribute<int>( "column" ),
                    RowSpan = element.GetAttribute<int>( "rowspan" ),
                    ColumnSpan = element.GetAttribute<int>( "columnspan" ),
                    FunctionGroup = element.GetAttribute<string>( "functiongroup" ),
                    Function = element.GetAttribute<string>( "function" ),
                    Icon = element.GetAttribute<string>( "icon" ),
                    StatusBindingResource = element.GetAttribute<string>( "statusresource" ),
                    Important = element.GetAttribute<bool>( "important" ),
                };
            }

            return null;
        }

        public override string ToString() { return Title; }

        #endregion Public Methods
    }
}
